home *** CD-ROM | disk | FTP | other *** search
/ Otherware / Otherware_1_SB_Development.iso / mac / hypercar / xcmd / dartxcmd.sit / Dartmouth XCMD's 3.1 / card_7519.txt < prev    next >
Encoding:
Text File  |  1989-06-02  |  24.9 KB  |  910 lines

  1. -- card: 7519 from stack: in.1
  2. -- bmap block id: 14236
  3. -- flags: 0000
  4. -- background id: 8327
  5. -- name: XScrollBox
  6. ----- HyperTalk script -----
  7. on opencard
  8.   set the scroll of card field 1 to 0
  9.   set the scroll of card field 2 to 0
  10.   pass opencard
  11. end opencard
  12.  
  13. on Install
  14.   get ChooseTargetStack()
  15.   InstallResource XFCN,XScrollBox,it
  16.   InstallResource DITL,XScrollBox,it
  17.   InstallResource DLOG,XScrollBox,it
  18. end Install
  19.  
  20.  
  21. -- part 2 (field)
  22. -- low flags: 01
  23. -- high flags: 4007
  24. -- rect: left=384 top=58 right=286 bottom=491
  25. -- title width / last selected line: 0
  26. -- icon id / first selected line: 0 / 0
  27. -- text alignment: 0
  28. -- font id: 3
  29. -- text size: 9
  30. -- style flags: 0
  31. -- line height: 12
  32. -- part name: scroller
  33.  
  34.  
  35. -- part 3 (button)
  36. -- low flags: 00
  37. -- high flags: 8003
  38. -- rect: left=76 top=298 right=320 bottom=176
  39. -- title width / last selected line: 0
  40. -- icon id / first selected line: 0 / 0
  41. -- text alignment: 1
  42. -- font id: 0
  43. -- text size: 12
  44. -- style flags: 0
  45. -- line height: 16
  46. -- part name: XScrollBox
  47. ----- HyperTalk script -----
  48. on mouseUp
  49.   get XScrollBox(2,"Choose one of these:",card field "scroller","Help")
  50.   go this card
  51.   if it is "Help" then
  52.     answer "You pushed the 'Help' button."
  53.   else if it is empty then
  54.     answer "You pushed the 'Cancel' button."
  55.   else
  56.     answer "Your choice was: " & it
  57.   end if
  58. end mouseUp
  59.  
  60.  
  61.  
  62. -- part 5 (field)
  63. -- low flags: 01
  64. -- high flags: 2007
  65. -- rect: left=17 top=31 right=286 bottom=382
  66. -- title width / last selected line: 0
  67. -- icon id / first selected line: 0 / 0
  68. -- text alignment: 0
  69. -- font id: 3
  70. -- text size: 10
  71. -- style flags: 0
  72. -- line height: 13
  73. -- part name: Documentation
  74.  
  75.  
  76. -- part 6 (button)
  77. -- low flags: 00
  78. -- high flags: 8003
  79. -- rect: left=299 top=298 right=320 bottom=438
  80. -- title width / last selected line: 0
  81. -- icon id / first selected line: 0 / 0
  82. -- text alignment: 1
  83. -- font id: 0
  84. -- text size: 12
  85. -- style flags: 0
  86. -- line height: 16
  87. -- part name: Show LSC Source
  88. ----- HyperTalk script -----
  89. on mouseUp
  90.   get the visible of card field "source"
  91.   set the visible of card field "source" to not it
  92.   if it is false then
  93.     set the name of me to "Hide LSC Source"
  94.   else
  95.     set the name of me to "Show LSC Source"
  96.   end if
  97. end mouseUp
  98.  
  99.  
  100.  
  101. -- part 7 (field)
  102. -- low flags: 81
  103. -- high flags: 0007
  104. -- rect: left=18 top=31 right=290 bottom=489
  105. -- title width / last selected line: 0
  106. -- icon id / first selected line: 0 / 0
  107. -- text alignment: 0
  108. -- font id: 3
  109. -- text size: 10
  110. -- style flags: 0
  111. -- line height: 13
  112. -- part name: Source
  113.  
  114.  
  115. -- part contents for card part 2
  116. ----- text -----
  117. able
  118. baker
  119. charlie
  120. dog
  121. ernest
  122. fox
  123. gamma
  124. horse
  125. ice cream
  126. jumping jack flash
  127. knockwurst
  128. liver
  129. monkey
  130. no way, jose
  131. occularity
  132. penelope
  133. qwerty
  134. rapscallion
  135. salubrious
  136. twinkle toes
  137. underwhelmed
  138. vermin
  139. wascally wabbit
  140. yokel
  141. zenzational
  142.  
  143. -- part contents for card part 5
  144. ----- text -----
  145. XScrollBox version 1.7
  146. Roger Brown
  147.  
  148. XScrollBox is a HyperCard XFCN that creates a scrolling selection dialog box from any multi-lined container.  Each line of the container is made into a selection line in the dialog. Only one line can be selected. 
  149.  
  150. The return value has two items: the number of the selection and the text of the selection. These are separated by commas as in normal HyperCard format. 
  151.    
  152. Selection can be made by :
  153.    1. double-clicking on a line.
  154.    2. single-clicking on a line, then pressing the OK button.
  155.    3. single-clicking on a line, then pressing the Return key.
  156.    4. typing the first letter(s) of a selection, then doing 1,2, or 3.
  157.      (Note: type selection assumes that the lines are ordered       
  158.        alphabetically)
  159.    5. scrolling with up and down arrow keys, then doing 1,2 or 3.
  160.    
  161.    If the Cancel button is pressed, a null string is returned.
  162.    
  163.    It requires that the DITL and DLOG resources (1345) packaged  
  164.    with it are in the stack.
  165.    
  166.   The dialog is centered on the screen and sized to hold the width of the longest line and/or the prompt line, whichever is widest. It will not overrun the width of a  Mac+ screen.
  167.  
  168. INVOKING XScrollBox
  169.  
  170.   get XScrollBox(first,prompt,container,userButton)
  171.         
  172.    where   first  is a default selection in the list - either a number or                   
  173.                           a  text string (0 if none).
  174.                 prompt is a string to prompt the user. This appears at the 
  175.                           top of the dialog box.
  176.                 container is any hypercard container (field, variable), 
  177.                            presumed to be multi-lined.
  178.                 UserButton  is the name for an optional author specified 
  179.                            button. If this button is pressed, its name is 
  180.                            returned further processing by the script.  
  181.                    
  182.  
  183. EXAMPLE
  184.  
  185.  ex.  get XScrollBox(1,"Choose:",card field 1,"Help")
  186.         if OK is pressed, returns : 1,text of line 1 of card field 1
  187.  
  188.  
  189. REVISION HISTORY
  190. 1.1 center dialog box on any size screen
  191. 1.2 - add selection scrolling by typing and by cursor keys
  192. 1.3 - add text of chosen item to return value
  193. 1.4 - 3/2/88   add optional user button
  194. 1.6 - 5/12/89  fixed problem with selecting the first item the 
  195.           first time when type-selecting.  Fixed problem where typing 
  196.           an item exactly selects the one after it.
  197. 1.7 - 5/15/89 made it compile under LSC 3.0.
  198.  
  199.  
  200.  
  201. -- part contents for card part 7
  202. ----- text -----
  203. /* XScrollBox1.7.c */
  204. /* ┬⌐ Trustees of Dartmouth College */
  205. /* written in LightSpeed C  ┬⌐ Think Technologies, Inc */
  206. /* by Roger Brown 3/2/88  Courseware Development group */
  207.  
  208. /* This is a HyperCard XFCN that creates a scrolling selection dialog box from
  209.    any multi-lined container. Syntax is:
  210.    
  211.         get XScrollBox(first,prompt,container,userButton)
  212.    
  213.    ex.      get XScrollBox(1,"Choose:",card field 1,"Help")
  214.   
  215.    returns: 1,text of line 1 of card field 1
  216.    
  217.    where    first      is a default selection in the list - either a number
  218.                                or a text string (0 if none).
  219.             prompt      is a string to prompt the user. This appears at the
  220.                               top of the dialog box.
  221.             container   is any hypercard container (field, variable), presumed to be 
  222.                               multi-lined.
  223.             UserButton  is the name for an optional author specified button.
  224.                               If this button is pressed, its name is returned
  225.                               for further processing by the script.  
  226.                     
  227.    Each line of the container is made into a selection line in the
  228.    dialog. Only one line can be selected. 
  229.    
  230.    The return value has two items: the number of the selection and the text of
  231.    the selection. These are separated by commas as in normal HyperCard format. 
  232.    
  233.    Selection can be made by:
  234.    
  235.    1. double-clicking on a line.
  236.    2. single-clicking on a line, then pressing the OK button.
  237.    3. single-clicking on a line, then pressing the Return key.
  238.    4. typing the first letter(s) of a selection, then doing 1,2, or 3.
  239.       (Note: type selection assumes that the lines are ordered alphabetically)
  240.    5. scrolling with up and down arrow keys, then doing 1,2 or 3.
  241.    
  242.    If the Cancel button is pressed, a null string is returned.
  243.    
  244.    It requires that the DITL and DLOG resources packaged with it are in the stack.
  245.    
  246.    The dialog box is centered in the card window.
  247.    
  248.    To compile: create a project with this and MacTraps. Build as code resource type
  249.    XFCN, ID 1345, name XScrollBox.
  250. */
  251.  
  252. /* version 1.7: LSC 3.0 compiled  5/15/89 */
  253. /* version 1.6: fixed problem with selecting the first item the first time
  254.    when type-selecting.  Fixed problem where typing an item exactly selects
  255.    the one after it.
  256. */
  257.  
  258.  
  259. #include "stddata_ctype.c"
  260. #include "QuickDraw.h"
  261. #include "EventMgr.h"
  262. #include "WindowMgr.h"
  263. #include "ResourceMgr.h"
  264. #include "ControlMgr.h"
  265. #include "DialogMgr.h"
  266. #include "strings.c"
  267. #include "ListMgr.h"
  268. #include "ToolboxUtil.h"
  269. #include "HyperXCmd.h"
  270. #include "XCmdGlue.inc.c"
  271. #include "SetUpA4.h"
  272.  
  273.  
  274. #define FALSE 0
  275. #define TRUE !FALSE
  276.  
  277. /* globals */
  278.  
  279. #define kOKbutton 1
  280. #define kCancel 2
  281. #define kPrompt 3
  282. #define kListItem 4
  283. #define kOutliner 5
  284. #define kUserButton 6
  285. #define kTyping 99
  286.  
  287. int kScrollBarWidth = 15;
  288.  
  289. int kStdLDEF = 0;
  290. int kDialogId = 1345;
  291. int kStringListId = 1345;
  292.  
  293. int gCellWidth;
  294. int gCellHeight = 16;
  295.  
  296. Rect dialogRect,listRect,cardRect;
  297. ListHandle theList;
  298. DialogPtr theListDialog;
  299. Str255 theResult,userButton;
  300. long theStartWith;
  301. Str255 startString;
  302. char startIsString;
  303. Handle resultHandle;
  304. CursHandle theCursor;
  305. char collector[32];
  306. int charPos;
  307. long charTime;
  308.  
  309. XCmdBlockPtr    gParamPtr;
  310.  
  311.  
  312. /* return max of 2 integers */
  313.  
  314. max(a,b)
  315. int a,b;
  316.     if (a>b) return a;
  317.     return b;
  318. }
  319.  
  320. /* return min of 2 integers */
  321.  
  322. min(a,b)
  323. {
  324.     if (a<b) return a;
  325.     return b;
  326. }
  327.  
  328.  
  329. /* Get HyperCard comma delimited item i from item list string s. */
  330.  
  331. int GetHCItem(s,i)
  332. char *s;
  333. int i;
  334. {
  335.     int c,len,count,j;
  336.     char temp[32];
  337.     long it;
  338.     
  339.     count = j = 0;
  340.     len = strlen(s);
  341.     for (c=0;c<len;c++) {
  342.         if (s[c]==',') {
  343.             count = count + 1;
  344.             if (count==i) break;
  345.             j = 0;
  346.         }
  347.         else {
  348.             temp[j] = s[c];
  349.             j++;
  350.             if (c==(len-1)) {     /* last item, no comma */
  351.                 count = count+1;
  352.                 break;
  353.             }
  354.         }
  355.     }
  356.     if (count < i) strcpy(temp,"");  /* no item there */
  357.     temp[j] = 0;
  358.     CtoPstr(temp);
  359.     StringToNum(temp,&it);
  360.     return (int)it;
  361. }
  362.  
  363. /* Get the coordiates of the HyperCard card window so we can center the dialog on it. */
  364.  
  365. GetCardRect(paramPtr,itsRect)
  366. XCmdBlockPtr    paramPtr;
  367. Rect *itsRect;
  368. {
  369.     Handle theResult;
  370.     long len;
  371.     Str255 str;
  372.     int i;
  373.     
  374.     strcpy(str,"the rect of card window");
  375.     CtoPstr((char *)str);
  376.     theResult = EvalExpr(paramPtr,str);
  377.     len = GetHandleSize(theResult);
  378.     HLock(theResult);
  379.     BlockMove(*theResult,str,len);
  380.     HUnlock(theResult);
  381.     DisposHandle(theResult);
  382.     itsRect->left = GetHCItem(str,1);
  383.     itsRect->top = GetHCItem(str,2);
  384.     itsRect->right = GetHCItem(str,3);
  385.     itsRect->bottom = GetHCItem(str,4);
  386. }
  387.  
  388. /* user item in dialog box to outline the default (ok) button */
  389.  
  390. pascal void OutlineButton (myWindow,itemNo)
  391. WindowPtr myWindow;
  392. int itemNo;
  393. {
  394.     int iType;
  395.     Handle iHandle;
  396.     Rect iBox;
  397.     
  398.     SetUpA4();
  399.     GetDItem(theListDialog, kOKbutton, &iType, &iHandle, &iBox);
  400.     InsetRect(&iBox, -4, -4);
  401.     PenSize(3, 3);
  402.     FrameRoundRect(&iBox, 16, 16);
  403.     PenNormal();
  404.     RestoreA4();
  405. }
  406.  
  407. /* User item in dialog box to display the selectin list */
  408.  
  409. pascal void DrawListItem (myWindow,itemNo)
  410. WindowPtr myWindow;
  411. int itemNo;
  412. /* draw the selection list */
  413. {
  414.     RgnHandle theRgn;
  415.     Rect listFrame;
  416.     
  417.     SetUpA4();
  418.     listFrame = (**theList).rView;
  419.     InsetRect(&listFrame, -1, -1);
  420.     FrameRect(&listFrame);
  421.     theRgn = NewRgn();
  422.     RectRgn(theRgn, &(*theListDialog).portRect);
  423.     LUpdate(theRgn, theList);
  424.     DisposeRgn(theRgn);
  425.     RestoreA4();
  426. }
  427.  
  428. /* change a character to upper case */
  429.  
  430. int toupper(c)
  431. char    c;
  432. {
  433.     return( (c>='a')&&(c<='z') ? (c-('a'-'A')) : c );
  434. }
  435.  
  436. /* string selection logic for selection via typed characters */
  437.  
  438. pascal int MySelect(aPtr,bPtr,aLen,bLen)
  439. Ptr aPtr,bPtr;int aLen,bLen;
  440. {
  441.     /* return 0 if string a >= string b, else return 1 */
  442.     
  443.     int p,len,compare;
  444.     char ca,cb;
  445.     
  446.     compare = 0;
  447.     if (aLen < bLen) len = aLen;
  448.     else len = bLen;
  449.     p = 0;
  450.     while (p < len) {
  451.         ca = toupper(*(aPtr+p));
  452.         cb = toupper(*(bPtr+p));
  453.         if (ca < cb) {
  454.             compare = 1;
  455.             break;
  456.         }
  457.         p++;
  458.     }
  459.     if ((compare==0)&&(aLen < bLen)) compare = 1;
  460.     return compare;
  461. }
  462.  
  463. /* scroll selection list up or down */
  464.  
  465. VerticalScroll(c)
  466. char c;
  467. {
  468.     Cell oldCell,aCell;
  469.         
  470.     SetUpA4();
  471.     SetPt(&oldCell,0,0);
  472.     if (!LGetSelect(TRUE,&oldCell,theList)) {  /* get current selection */
  473.         SysBeep(0); /* no current selection */
  474.         return;
  475.     }
  476.     if (c==30) {
  477.         SetPt(&aCell,0,max(0,oldCell.v-1));
  478.     }
  479.     else if (c==31) {
  480.         SetPt(&aCell,0,min((**theList).dataBounds.bottom-1,oldCell.v+1));
  481.     }
  482.     if (EqualPt(oldCell,aCell)==1) {
  483.         SysBeep(0);
  484.         return;
  485.     }
  486.     LSetSelect(FALSE,oldCell,theList);  /* clear current selection */
  487.     LSetSelect(TRUE,aCell,theList);     /* set the new one */   
  488.     LAutoScroll(theList);
  489.     RestoreA4();
  490. }
  491.  
  492. /* Select by typing - a filter proc for ModalDialog. Simulates SGGetFile dialog action. */
  493.  
  494. pascal char NameSelect(theDialog,theEvent,itemHit)
  495. DialogPtr theDialog;EventRecord *theEvent;int *itemHit;
  496. {
  497.     int c;
  498.     long dummy;
  499.     int iType;
  500.     Handle iHandle;
  501.     Rect iBox;
  502.     char result;
  503.     
  504.     SetUpA4();
  505.     result = FALSE;
  506.     if ((theEvent->what == keyDown)||(theEvent->what == autoKey)) {
  507.         if (TickCount() > charTime) charPos = 0;
  508.         collector[charPos] = BitAnd(theEvent->message,charCodeMask);
  509.         if ((collector[charPos] ==13)||(collector[charPos]==3)) {  /* is CR, use as normal */
  510.             *itemHit = 1;
  511.             GetDItem(theListDialog, kOKbutton, &iType, &iHandle, &iBox);
  512.             HiliteControl(iHandle,inButton);
  513.             result = TRUE;
  514.         }
  515.         else if ((collector[charPos]==31)||(collector[charPos]==30)) {  /* cursor up/down */
  516.             VerticalScroll(collector[charPos]);
  517.             charPos = 0;
  518.         }
  519.         else {
  520.             charPos++;
  521.             collector[charPos] = 0;
  522.             *itemHit = 99;
  523.             result = TRUE;
  524.             charTime = TickCount()+45; 
  525.         }
  526.     }
  527.     RestoreA4();
  528.     return result;
  529. }
  530.  
  531. /* Create, size, center, and fill in the selection box. Retuens 0 if any errors occur. */
  532.  
  533. int SetupScrollBox (prompt,theField)
  534. char *prompt;
  535. char *theField;
  536. {
  537.     Rect dataBounds, itemBox,tempRect;
  538.     char doVScroll, doHScroll;
  539.     Point cellSize;
  540.     Cell aCell,oldCell;
  541.     int i,j, itemType,x,y;
  542.     ControlHandle itemHandle;
  543.     Str255 aString;
  544.     long len;
  545.     int fieldLen;
  546.     int numLines,lineLen,maxLen,row;
  547.     char done,c;
  548.     int screenCenterX,screenCenterY;
  549.     int dialogWidth;
  550.     int dialogCenterX,dialogCenterY;
  551.     int itemWidth,itemHeight;
  552.     int itemHit;
  553.     GrafPtr gp;
  554.     Handle tempHandle;
  555.     int numButtons;
  556.     
  557.     if (strlen(userButton)>0) numButtons = 3;
  558.     else numButtons = 2;
  559.     
  560.     /* size the dialog box */
  561.     
  562.     dialogWidth = 200+8*strlen(userButton); /* minimum width to fit buttons at bottom */
  563.                                /* make sure the prompt fits */
  564.     dialogWidth = max(dialogWidth,strlen(prompt)*8+20);
  565.         
  566.     /* find the longest line */
  567.     
  568.     lineLen = maxLen = numLines = 0;
  569.     fieldLen = strlen(theField);
  570.     for (i=0;i<fieldLen;i++) {
  571.         c = theField[i];
  572.         if ((c ==13)||(i==(fieldLen-1))) {
  573.             maxLen = max(lineLen,maxLen);
  574.             lineLen = 0;
  575.             numLines++;
  576.         }
  577.         else lineLen++;
  578.     }
  579.     gCellWidth = maxLen*8;
  580.     
  581.     /* size it to have 10 lines visible and 8 pixels per character */
  582.     /* leave room at the top for the prompt and at the bottom for
  583.        the OK button */
  584.        
  585.     dialogWidth = max(dialogWidth,gCellWidth+20+16);
  586.     dialogWidth = min(dialogWidth,490);  /* chop to screen width */
  587.     
  588.     gCellWidth = dialogWidth-20-16;
  589.     
  590.     SetRect(&dialogRect,0,0,dialogWidth,75+(10*gCellHeight));
  591.     SetRect(&listRect,10,30,10+gCellWidth,30+(10*gCellHeight));
  592.     
  593.     /* now center it in the current port */
  594.         
  595.     screenCenterX = cardRect.left + (cardRect.right - cardRect.left)/2;
  596.     screenCenterY = cardRect.top + (cardRect.bottom - cardRect.top)/2;
  597.  
  598.     dialogCenterX = dialogRect.left + (dialogRect.right-dialogRect.left)/2;
  599.     dialogCenterY = dialogRect.top + (dialogRect.bottom-dialogRect.top)/2;
  600.             
  601.     OffsetRect(&dialogRect,screenCenterX-dialogCenterX,
  602.                 screenCenterY-dialogCenterY);
  603.     
  604.     dialogCenterX = dialogRect.left + (dialogRect.right-dialogRect.left)/2;
  605.     dialogCenterY = dialogRect.top + (dialogRect.bottom-dialogRect.top)/2;
  606.     
  607.     /* now get the dialog resource */
  608.     
  609.     tempHandle = GetResource('DLOG',kDialogId);
  610.     if (tempHandle==NULL) {
  611.         return 0;
  612.     }
  613.  
  614.     theListDialog = GetNewDialog(kDialogId, NULL,(WindowPtr)NULL);
  615.  
  616.     /* size it and center it */
  617.     
  618.     MoveWindow(theListDialog,dialogRect.left,dialogRect.top,FALSE);
  619.     SizeWindow(theListDialog,dialogRect.right-dialogRect.left,
  620.                 dialogRect.bottom-dialogRect.top,FALSE);
  621.     
  622.     /* adjust the ok button */
  623.     
  624.     GetDItem(theListDialog,kOKbutton,&itemType,&itemHandle,&itemBox);
  625.     itemWidth = (itemBox.right-itemBox.left);
  626.     itemHeight = (itemBox.bottom-itemBox.top);
  627.     x = listRect.left  + 
  628.         (listRect.right+16-listRect.left)/(numButtons*2) - itemWidth/2;
  629.     y = listRect.bottom + 15;   
  630.     SetRect(&itemBox,x,y,x+itemWidth,y+itemHeight); 
  631.     MoveControl(itemHandle,itemBox.left,itemBox.top);
  632.     SetDItem(theListDialog,kOKbutton,itemType,itemHandle,&itemBox);
  633.         
  634.     /* adjust the cancel button */
  635.     
  636.     GetDItem(theListDialog,kCancel,&itemType,&itemHandle,&itemBox);
  637.     itemWidth = (itemBox.right-itemBox.left);
  638.     itemHeight = (itemBox.bottom-itemBox.top);
  639.     x = listRect.left  + 
  640.         (numButtons*2-1)*(listRect.right+16-listRect.left)/(numButtons*2)
  641.          - itemWidth/2;
  642.     y = listRect.bottom + 15;   
  643.     SetRect(&itemBox,x,y,x+itemWidth+100,y+itemHeight); 
  644.     MoveControl(itemHandle,itemBox.left,itemBox.top);
  645.     SetDItem(theListDialog,kCancel,itemType,itemHandle,&itemBox);
  646.     
  647.     /* set up the user button if there is one */
  648.         
  649.     GetDItem(theListDialog,kUserButton,&itemType,&itemHandle,&itemBox);
  650.     CtoPstr((char *)userButton);
  651.     SetCTitle(itemHandle,userButton);
  652.     itemHeight = (itemBox.bottom-itemBox.top);
  653.     itemWidth = 8*strlen(userButton);
  654.     x = listRect.left  + 
  655.         (numButtons*(listRect.right+16-listRect.left)/(numButtons*2))
  656.         - itemWidth/2;
  657.     x = x + 2;        /* to balance OK button outliner */
  658.     y = listRect.bottom + 15;
  659.     SetRect(&itemBox,x,y,x+itemWidth,y+itemHeight);
  660.     MoveControl(itemHandle,itemBox.left,itemBox.top);
  661.     SizeControl(itemHandle,itemWidth,itemHeight);
  662.     SetDItem(theListDialog,kUserButton,itemType,itemHandle,&itemBox);
  663.     PtoCstr((char *)userButton);
  664.  
  665.     
  666.     /* adjust the prompt string and fill it in */
  667.     
  668.     GetDItem(theListDialog,kPrompt,&itemType,&itemHandle,&itemBox);
  669.     itemWidth = strlen(prompt)*8;
  670.     CtoPstr((char *)prompt);    
  671.     SetIText(itemHandle,prompt);
  672.     itemHeight = (itemBox.bottom-itemBox.top);
  673.     x = listRect.left  + 
  674.         (listRect.right+16 - listRect.left)/2 - itemWidth/2;
  675.     y = listRect.top - 5;   
  676.     SetRect(&itemBox,x,y-itemHeight,x+itemWidth,y);     
  677.     SetDItem(theListDialog,kPrompt,itemType,itemHandle,&itemBox);
  678.  
  679.     
  680.     /* now create the text list */
  681.     
  682.     SetRect(&dataBounds, 0, 0, 1, numLines);
  683.     SetPt(&cellSize, gCellWidth, gCellHeight);
  684.     theList = LNew(&listRect, &dataBounds, cellSize,
  685.          kStdLDEF, (WindowPtr)theListDialog, FALSE, FALSE, FALSE, TRUE);
  686.     (**theList).selFlags = lOnlyOne;
  687.      
  688.     /* now fill in its text */
  689.     /* squeeze out control characters 2/27/88 */
  690.     
  691.     j = 0;row = 0;
  692.     for (i=0;i<fieldLen;i++) {
  693.         if (theField[i] > 31) {
  694.             aString[j] = theField[i];
  695.             j++;
  696.         }
  697.         if ((theField[i] ==13)||(i==(fieldLen-1))) {
  698.             aString[j] = 0;
  699.             SetPt(&aCell,0,row);
  700.             row ++;
  701.             lineLen = strlen(aString);
  702.             LSetCell(&aString[0], lineLen, aCell, theList);
  703.             j = 0;
  704.         } 
  705.     }
  706.     if (startIsString) {
  707.         SetPt(&oldCell,0,0);
  708.         LGetSelect(TRUE,&oldCell,theList);  /* get current selection*/
  709.         SetPt(&aCell,0,0);
  710.         if (LSearch(startString,strlen(startString),MySelect,&aCell,theList)) {
  711.             if (!EqualPt(oldCell,aCell)) {
  712.                 LSetSelect(FALSE,oldCell,theList);  /* clear current selection */
  713.                 LSetSelect(TRUE,aCell,theList);     /* set the new one */   
  714.                 LAutoScroll(theList);
  715.             }
  716.         }
  717.     }
  718.     else if ((theStartWith > 0)&&(theStartWith<numLines)); {
  719.         SetPt(&aCell, 0,theStartWith-1);
  720.         LSetSelect(TRUE, aCell, theList);
  721.         if (theStartWith>10) LAutoScroll(theList);
  722.     }
  723.     LDoDraw(TRUE, theList);
  724.     
  725.     
  726.     /* now complete the two user items of the dialog */
  727.     
  728.     itemBox = listRect;
  729.     itemBox.right = itemBox.right + kScrollBarWidth;
  730.  
  731.     SetDItem(theListDialog, kListItem, userItem, DrawListItem, &itemBox);
  732.     GetDItem(theListDialog,kOKbutton,&itemType,&itemHandle,&itemBox);
  733.     SetDItem(theListDialog, kOutliner, userItem + itemDisable, OutlineButton, &itemBox);
  734.     
  735.     /* present the window up front */
  736.     
  737.     ShowWindow(theListDialog);
  738.     BringToFront(theListDialog);
  739.  
  740.     return 1;
  741. }
  742.  
  743. DoListDialog ()
  744.  
  745. /* pose the dialog and handle it */
  746.  
  747. {
  748.     int itemHit;
  749.     Point aPoint;
  750.     Cell oldCell,aCell;
  751.     Boolean somethingSelected;
  752.     Str255 temp;
  753.     
  754.     itemHit = charPos = 0;
  755.     while (1) {
  756.         RememberA4();
  757.         ModalDialog(NameSelect, &itemHit);
  758.         switch (itemHit) {
  759.             case kOKbutton :
  760.                 return 1;
  761.             break;
  762.             case kCancel:
  763.                 return 0;
  764.             break;
  765.             case kListItem:
  766.                 SetPort(theListDialog);
  767.                 GetMouse(&aPoint);
  768.                 if (LClick(aPoint, 0, theList)) return 1;
  769.             break;
  770.             case kUserButton:
  771.                 return 2;
  772.             break;
  773.             case kTyping:
  774.                 SetPt(&oldCell,0,0);
  775.                 /* get current selection */
  776.                 somethingSelected = LGetSelect(TRUE,&oldCell,theList); 
  777.                 SetPt(&aCell,0,0);
  778.                 if (LSearch(collector,strlen(collector),MySelect,&aCell,theList)) {
  779.                     if ((somethingSelected==FALSE) || (!EqualPt(oldCell,aCell))) {
  780.                         LSetSelect(FALSE,oldCell,theList);  /* clear current selection */
  781.                         LSetSelect(TRUE,aCell,theList);     /* set the new one */   
  782.                         LAutoScroll(theList);
  783.                         /*strcpy(temp,"put ");
  784.                         strcat(temp,collector);
  785.                         CtoPstr((char*)temp);
  786.                         SendHCMessage(gParamPtr,temp);*/
  787.                     }
  788.                 }
  789.             break;
  790.         }
  791.     }
  792. }
  793.  
  794. /* get the text of the selection made */
  795.  
  796. GetListSelection (aString)
  797. char *aString;
  798. {
  799.     char someSelect;
  800.     Cell aCell;
  801.     int stringLength,t,b,i;
  802.     Str255 num;
  803.     long n;
  804.     
  805.     SetPt(&aCell, 0, 0);
  806.     someSelect = LGetSelect(TRUE, &aCell, theList);
  807.     if (someSelect==TRUE) {
  808.         stringLength = 255;
  809.         LGetCell(aString, &stringLength, aCell, theList);
  810.         n = aCell.v+1;
  811.         NumToString(n,num);
  812.         PtoCstr((char *)num);
  813.         *(aString+stringLength) = 0;
  814.         strcat(num,",");
  815.         strcat(num,aString);
  816.         strcpy(aString,num);
  817.     }
  818.     else {
  819.         strcpy(aString,"");
  820.     }
  821. }
  822.  
  823. /* clean up memory */
  824.  
  825. PrepareToExit()
  826. {   
  827.     if (theList != NULL) LDispose(theList);
  828.     if (theListDialog != NULL) DisposDialog(theListDialog);
  829. }
  830.  
  831. /* create scroll box, present it, return user's selection */
  832.  
  833. pascal void XScrollBox(paramPtr)
  834. XCmdBlockPtr    paramPtr;
  835. {   
  836.     Str255 result;
  837.     Ptr start;
  838.     Ptr thePrompt;
  839.     Ptr theField;
  840.     Ptr theUserButton;
  841.     int status,i;
  842.     Size len;
  843.     
  844.     gParamPtr = paramPtr;
  845.     if (paramPtr->paramCount < 3) {
  846.         strcpy(theResult,"Not enough parameters in XScrollBox");
  847.     }   
  848.     else {
  849.         theCursor = GetCursor(watchCursor);
  850.         SetCursor(*theCursor);
  851.         for (i=0;i<5;i++) {
  852.             MoveHHi(paramPtr->params[i]);
  853.             HLock(paramPtr->params[i]);
  854.         }
  855.         start = *(paramPtr->params[0]);
  856.         startIsString = TRUE;
  857.         for (i=0;i<strlen(start);i++) {
  858.             if (!isalpha(start[i])) {
  859.                 startIsString = FALSE;
  860.                 break;
  861.             }
  862.         }
  863.         if (startIsString) strcpy(startString,start);
  864.         else {
  865.             CtoPstr((char *)start);  
  866.             StringToNum(start,&theStartWith);
  867.         }
  868.         thePrompt = *(paramPtr->params[1]);
  869.         theField = *(paramPtr->params[2]);
  870.         theUserButton = *(paramPtr->params[3]);
  871.         if (GetHandleSize(paramPtr->params[3])>0)
  872.             strcpy(userButton,theUserButton);
  873.         else strcpy(userButton,"");
  874.             
  875.         GetCardRect(paramPtr,&cardRect);
  876.         status = SetupScrollBox(thePrompt,theField);
  877.         InitCursor();
  878.         if (status==1) {
  879.             status = DoListDialog();
  880.             if (status==1) GetListSelection(theResult);
  881.             else if (status==2) strcpy(theResult,userButton);
  882.             else strcpy(theResult,"");
  883.         }
  884.         else strcpy(theResult,"Can't find dialog resource 1345 for XScrollBox XFCN");
  885.     }
  886.     len = 1+strlen(theResult);
  887.     resultHandle = NewHandle(len);
  888.     HLock(resultHandle);
  889.     BlockMove(theResult,*resultHandle,len);
  890.     HUnlock(resultHandle);
  891.     paramPtr->returnValue = resultHandle;
  892.     for (i=0;i<5;i++) HUnlock (paramPtr->params[i]);
  893.     return;
  894. }
  895.  
  896. /* this is the entry point for the XFCN */
  897.  
  898. pascal void main(paramPtr)
  899. XCmdBlockPtr    paramPtr;
  900. {
  901.     RememberA0();
  902.     SetUpA4();
  903.     XScrollBox(paramPtr);       /* run the main event loop */   
  904.     PrepareToExit();        /* tidy up */
  905.     RestoreA4();        /* and this also */
  906.     return;
  907. }
  908.  
  909.